package cn.bluethink.zentao.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.bluethink.zentao.entity.ZtStatisticsEntity;
import cn.bluethink.zentao.entity.ZtTaskEntity;
import cn.bluethink.zentao.entity.ZtUserEntity;
import cn.bluethink.zentao.filter.ZentaoFilter;
import cn.bluethink.zentao.mapper.ZentaoMapper;
import cn.bluethink.zentao.model.ZtProjectStatistics;
import cn.bluethink.zentao.model.ZtStatistics;
import cn.bluethink.zentao.model.ZtTask;
import cn.bluethink.zentao.model.ZtTaskStatus;
import cn.bluethink.zentao.model.ZtUser;
import cn.bluethink.zentao.page.PageInfo;
import cn.bluethink.zentao.utils.DateUtil;

@Service
public class ZenTaoService {

	@Autowired
	private ZentaoMapper zentaoMapper;

	/**
	 * 获取禅道用户列表（根据禅道项目Id和用户名）
	 * 
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	public PageInfo<ZtUser> ztusers(ZentaoFilter filter) throws Exception {
		Integer pageNum = filter.getPageNum();
		Integer pageSize = filter.getPageSize();
		// 1、获取项目Id
		Long id = filter.getId();
		filter.setId(id);
		PageHelper.startPage(pageNum, pageSize);
		// 5、根据条件查询 禅道用户列表
		Page<ZtUserEntity> users = (Page<ZtUserEntity>) zentaoMapper.zentaoUsers(filter);
		// 6、如果禅道用户列表不为空，将实体 转换为 业务模型
		if (users != null && users.size() > 0) {
			List<ZtUser> result = new ArrayList<>();
			users.forEach(u -> {
				ZtUser user = new ZtUser(u.getId(), u.getName(), null);
				result.add(user);
			});
			return new PageInfo<>(result, users);
		}
		return new PageInfo<>(new ArrayList<>());
	}

	/**
	 * 获取禅道任务列表
	 * 
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	public PageInfo<ZtTask> zttasks(ZentaoFilter filter) throws Exception {
		Integer pageNum = filter.getPageNum();
		Integer pageSize = filter.getPageSize();
		// 1、获取驿馆Id
		Long id = filter.getId();
		// 4、否则，将禅道项目Id 作为 查询条件
		filter.setId(id);
		PageHelper.startPage(pageNum, pageSize);
		// 5、根据条件查询 禅道任务列表
		Page<ZtTaskEntity> zttasks = (Page<ZtTaskEntity>) zentaoMapper.zentaoTasks(filter);
		// 6、如果禅道任务列表不为空，将实体 转换为 业务模型
		if (zttasks != null && zttasks.size() > 0) {
			return new PageInfo<>(entityToModel(zttasks), zttasks);
		}
		return new PageInfo<>(new ArrayList<>());
	}

	

   /**
	 * 获取禅道项目列表以及其项目成员，完成任务，延误任务
	 * 
	 * @return
	 * @throws Exception
	 */
	public PageInfo<ZtProjectStatistics> ztprojects(ZentaoFilter filter) throws Exception {
		
		if (filter.getBtime() == null || filter.getEtime() == null) { // 当前时间查询本周开始日期和结束日期
			dateToWeek(filter);
		}
		
        //禅道项目列表
		List<ZtStatisticsEntity> zentaoprojects = zentaoMapper.zentaoprojects();
		// 获取 项目- 完成任务个数 列表
		List<Map<String, Object>> projectFinish = zentaoMapper.projectFinish(filter);
		// 获取 项目- 延误任务个数 列表
		List<Map<String, Object>> projectDelay = zentaoMapper.projectDelay(filter);
		// 获取项目中 - 员工
		List<Map<String, Object>> projectStaffs = zentaoMapper.projectStaffs(filter);
		 
	    ArrayList<ZtProjectStatistics> result = new ArrayList<>();
	    
		// 如果禅道项目列表不为空
		if(zentaoprojects!=null && zentaoprojects.size()>0){
		  for (ZtStatisticsEntity project : zentaoprojects) {
			    Integer pid = project.getProject() == null?0:project.getProject();
			  for (Map<String, Object> finish : projectFinish) {
				  if(pid.equals(Integer.valueOf(finish.get("pid").toString()))){
					  // 将项目中已完成的任务set入实体类中
					  project.setProjectFinish(Integer.valueOf(finish.get("countTask").toString()));
				   }
				}
			  for (Map<String, Object> delay : projectDelay) {
				  if(pid.equals(Integer.valueOf(delay.get("pid").toString()))){
					  // 将项目中延误的任务总数set入实体类中
					  project.setProjectDelay(Integer.valueOf(delay.get("countTask").toString()));
				  }
			   }
			  for (Map<String, Object> staffs : projectStaffs) {
				  if(pid.equals(Integer.valueOf(staffs.get("pid").toString()))){
					  // 将项目员工总数set入实体类中
					  project.setProjectStaffs(Integer.valueOf(staffs.get("projectStaffs").toString()));
				  }
				
			   }
			  // 实体类转项目统计模型
			  ZtProjectStatistics projectStatisticsModel = project.creatProjectStatistics();
			  result.add(projectStatisticsModel);
			
		    }
		} 
		return new PageInfo<>(result);
		
	}


	/**
	 * 获取禅道中的周任务统计信息（主要提供监管组使用） 包括禅道中的每个用户对应的每周任务总个数，已完成任务个数，延误任务个数，完成率，延误率，
	 * 固定工时、预计工时、消耗工时、工作负载、消耗比和饱满度
	 * 
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	public PageInfo<ZtStatistics> zanTaoStatistics(ZentaoFilter filter) throws Exception {
		Integer pageNum = filter.getPageNum();
		Integer pageSize = filter.getPageSize();

		// 如果没有时间段，则默认查询本周任务统计情况
		if (filter.getBtime() == null || filter.getEtime() == null) { // 当前时间查询本周开始日期和结束日期
			dateToWeek(filter);
		}
		
		PageHelper.startPage(pageNum, pageSize);
		//禅道任务统计结果列表  实体咧转模型
		List<ZtStatistics> zantaoStatistics = taskStatistics(filter);

		return new PageInfo<>(zantaoStatistics);

	}

	/**
	 * 根据情况获取禅道异常任务列表及其备注
	 * 
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	public PageInfo<ZtTask> delaytasks(ZentaoFilter filter) throws Exception {
		Integer pageNum = filter.getPageNum();
		Integer pageSize = filter.getPageSize();

		if (filter.getBtime() == null || filter.getEtime() == null) { // 当前时间查询本周开始日期和结束日期
			dateToWeek(filter);
		}

		PageHelper.startPage(pageNum, pageSize);
		//根据条件获取禅道延误任务情况（包括备注）
		List<ZtTaskEntity> delaytasks = zentaoMapper.delaytasks(filter);

		List<ZtTask> result = new ArrayList<>();
		// 实体转业务模型
		if (delaytasks != null && delaytasks.size() > 0) {
			result = delaytasks.stream().map(t -> t.createZantaoTask()).collect(Collectors.toList());
		}
		return new PageInfo<>(result);
	}

	/**
	 * 禅道任务统计结果列表
	 * 
	 * @param filter
	 * @return
	 * @throws Exception
	 */
	public List<ZtStatistics> taskStatistics(ZentaoFilter filter) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date btime = sdf.parse(filter.getBtime());
		Date etime = sdf.parse(filter.getEtime());
		Double fixed=(double) (((etime.getTime()-btime.getTime())/((24*60*60*1000))+1)*8);//实际固定工时
		 
		List<ZtStatisticsEntity> zantaoStatistics = zentaoMapper.zentaoStatistics(filter);
		
		ArrayList<ZtStatistics> result = new ArrayList<>();

		// 获取用户 - 任务总个数 列表
		List<Map<String, Object>> zanTaoCountTask = zentaoMapper.getZenTaoCountTask(filter);
		// 获取 用户 - 完成任务个数 列表
		List<Map<String, Object>> zanTaoDoneTask = zentaoMapper.getZenTaoDoneTask(filter);
		// 获取 用户 - 延误任务个数 列表
		List<Map<String, Object>> zanTaoWaitTask = zentaoMapper.getZenTaoDelayTask(filter);
		// 任务完成个数存入实体类
		// 1、遍历任务统计列表
		for (ZtStatisticsEntity entity : zantaoStatistics) {
			// 2、获取当前任务执行者Id
			Integer uid = entity.getUid();
			// 3、如果当前任务执行者不为空并且 用户-任务总个数 列表不为空
			if (uid != null && zanTaoCountTask != null && zanTaoCountTask.size() > 0) {
				// 4、如果 用户 - 任务总个数 不为空，遍历该列表，设置该用户的任务总个数
				for (Map<String, Object> zanTaoCount : zanTaoCountTask) {
					if (uid.equals(Integer.parseInt(zanTaoCount.get("uid").toString()))) {
						entity.setZanTaoCountTask(Double.parseDouble(zanTaoCount.get("countTask").toString()));
					}
				}
				// 5、如果 用户 - 完成 任务个数 不为空，遍历该列表，设置该用户的完成任务个数
				if (zanTaoDoneTask != null && zanTaoDoneTask.size() > 0) {
					for (Map<String, Object> zanTaoDone : zanTaoDoneTask) {
						if (uid.equals(Integer.parseInt(zanTaoDone.get("uid").toString()))) {
							entity.setZanTaoDoneTask(Double.parseDouble(zanTaoDone.get("countTask").toString()));
						}
					}
				}
				// 6、如果 用户 - 延误任务个数 不为空，遍历该列表，设置该用户的延误任务个数
				if (zanTaoWaitTask != null && zanTaoWaitTask.size() > 0) {
					for (Map<String, Object> zanTaoWait : zanTaoWaitTask) {
						if (uid.equals(Integer.parseInt(zanTaoWait.get("uid").toString()))) {
							entity.setZanTaoDelayTask(Double.parseDouble(zanTaoWait.get("countTask").toString()));
						}
					}
				}
				
				entity.setFixed(fixed);//将实际固定工时set入实体类中
				
				
			}
			// 7、计算并设置禅道任务比率
			setRate(entity);
			// 8、实体转模型
			ZtStatistics egZantaoStatistics = entity.createStatustics();
			// 9、加到返回结果列表中
			result.add(egZantaoStatistics);
		}
		return result;
	}
	
	/**
	 * 将实体转换为模型
	 * 
	 * @param zttasks
	 * @return
	 * @throws Exception
	 */
	private List<ZtTask> entityToModel(List<ZtTaskEntity> zttasks) throws Exception {
		List<ZtTask> result = new ArrayList<>();
		zttasks.forEach(t -> {
			// 1、获取截止日期
			Date etime = t.getEtime();
			// 2、获取当前任务状态
			int status = t.getStatus();
			// 3、如果当前日期大于截止日期，将未开始和进行中的任务状态改为已延期/延期进行中
			if (DateUtil.dateCompare(new Date(), etime) > 0) {
				switch (status) {
				case ZtTaskStatus.STATUS_NEW:
					t.setStatus(status + 1);
					break;
				case ZtTaskStatus.STATUS_HANDLE:
					t.setStatus(status + 1);
					break;
				default:
					break;
				}
			}
			// 4、实体转换为模型
			result.add(t.createZantaoTask());
		});
		return result;
	}
	/**
	 * 计算每个统计对象对应的禅道任务相关比率并设置
	 * 
	 * @param entity
	 * @throws Exception
	 */
	private void setRate(ZtStatisticsEntity entity) throws Exception {
		// 1、如果任务总个数不为空，可进行计算，否则默认为0
		if (entity.getZanTaoCountTask() != null && entity.getZanTaoCountTask() != 0.0) {
			entity.setFinishRate(entity.getZanTaoDoneTask() / entity.getZanTaoCountTask() + "");
			entity.setDelayRate(entity.getZanTaoDelayTask() / entity.getZanTaoCountTask() + "");
		}
		// 2、工作负荷 禅道任务工作负荷 = 任务预计总工时/固定工时
		entity.setWorkload(entity.getEstimated() / entity.getFixed() + "");
		// 3、如果任务预计总工时不为null，并且不为0，计算任务消耗比 禅道任务消耗比 = 任务消耗总工时/预计总工时
		if (entity.getEstimated() != null && entity.getEstimated() > 0) {
			entity.setDepletionRate(entity.getDepletion() / entity.getEstimated() + "");
		}
		// 4、任务饱满度 禅道任务饱满度 = 任务消耗总工时/固定工时
		entity.setPlumpness(entity.getDepletion() / entity.getFixed() + "");
	}

	 
	
	/**
	 * 根据某一天计算这一星期的开始日期和结束日期
	 * 
	 * @param filter
	 * @throws Exception
	 */
	private void dateToWeek(ZentaoFilter filter) throws Exception {
		Date date = new Date();

		Map<String, String> dates = DateUtil.getTimeInterval(date);
		String weekBegin = dates.get("weekBegin");
		String weekEnd = dates.get("weekEnd");

		filter.setBtime(weekBegin);
		filter.setEtime(weekEnd);

	}

}
